package com.atguigu.dga.config;

import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.net.URI;
import java.net.URISyntaxException;

/**
 * Created by Smexy on 2023/10/25
 */
@Configuration
public class DgaConfig
{
    @Value("${hive.metastore.uris}")
    private String uri;

    /*
        对客户端的代码改造。
            1.客户端的创建是需要消耗一定资源的，那么应该是在需要时才创建，使用完之后关闭
                目前，当前这个方法返回的客户端是在容器一启动，就创建，一直保持连接。
                目标： 将Bean的创建改为需要时创建

            2.客户端对象不应该是单例的。这样一旦一个线程关闭了客户端，就会影响其他的线程。
                 客户端对象的创建应该是多实例的。每个线程在申请客户端时，有自己的客户端对象，
                 互不干扰。

           @Scope("prototype"): 告诉容器，这个对象的创建方式是多实例的。
                不写，等价于 @Scope("singleton")告诉容器，这个对象的创建方式是单实例的。
                单例的对象随着容器的创建而创建，而多实例的是在从容器中获取时，才会创建。


                注意： 多实例的对象，不能使用@Autowired注入！只能手动注入！
                    @Autowired注解是在容器一启动，就获取对象，为属性赋值！
     */
    @Bean
    @Scope("prototype")
    public HiveMetaStoreClient getHiveMetaStoreClient() throws MetaException {

        System.out.println("haha,客户端被创建了");
        org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
        // hive.metastore.uris: 是hive规定的，不可修改
        conf.set("hive.metastore.uris",uri);

        HiveMetaStoreClient client = new HiveMetaStoreClient(conf);

        return client;
    }

    @Value("${hdfs.uri}")
    private String hdfsUri;

    @Value("${hdfs.admin}")
    private String hdfsAdmin;

    //创建hdfs的客户端
    @Bean
    @Scope("prototype")
    public FileSystem getHDFSClient() throws Exception {
        return FileSystem.get(new URI(hdfsUri), new org.apache.hadoop.conf.Configuration(), hdfsAdmin);
    }
}
